package routers

import (
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/logs"
	"regexp"
	"smart_home/api/models"
	"smart_home/api/utils/token"
	"tools"
)

// 允许访问的页面
var allowPageRegx = []string{
	"/v2/mqtt/*",
	"/v2/object/*",
	"/v2/register",
	"/v2/login",
	"/v2/reset",
	"/v2/sms/*",
	"/v2/bot/*",
	"/v2/xfyun/*",
}

func init() {
	accessRegister()
}

func accessRegister() {
	check := func(ctx *context.Context) {
		// 并发流量控制

		// 是否允许权限访问
		for _, v := range allowPageRegx {
			reg := regexp.MustCompile(v)
			if reg.MatchString(ctx.Request.RequestURI) {
				return
			}
		}

		// token 认证
		tk := ctx.Input.Header("token")
		if len(tk) > 0 {
			// 防止重复提交【用户提交才限制】 ---- 此方式不完美，有违golang 通过通信来共享内存的初衷, 有时间重新设计
			key := tools.MD5Encode(fmt.Sprintf("%s-%s", ctx.Input.URL(), tk))
			if err := tools.RLock(key); err != nil {
				logs.Debug("操作频率过快，请稍后")
				repeatMsg(ctx)
				return
			}

			// token验证
			if t := token.Get(tk); t != nil {
				return
			}

			// 如果不通过认证，解锁
			defer tools.UnRLock(key)
		}

		// 服务器认证
		st := ctx.Input.Header("st")
		suid := ctx.Input.Header("suid")
		stc := beego.AppConfig.DefaultString("st", "mSArFMwLYNuMA5JfWeeJzpuJakEwekuC")
		if len(st) > 0 && len(suid) > 0 && st == stc {
			if user, err := models.GetUserById(suid); err == nil && user != nil {
				return
			}
		}

		// 认证失败
		failMsg(ctx)
		return
	}

	beego.InsertFilter("/v2/*", beego.BeforeRouter, check)
}

func failMsg(ctx *context.Context) {
	ctx.Output.JSON(map[string]interface{}{"code": 0, "msg": "权限不足", "result": nil}, true, false)
}

func repeatMsg(ctx *context.Context) {
	ctx.Output.JSON(map[string]interface{}{"code": 0, "msg": "操作频率过快，请稍后", "result": nil}, true, false)
}
